package spring.cloud.tasks.tasks_assign_manager.schedule;

import org.apache.curator.framework.CuratorFramework;
import spring.cloud.tasks.tasks_assign_manager.service.TaskItemAssignService;
import spring.cloud.tasks.tasks_assign_manager.task_item_assign.TaskItemAssign;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

public class ScheduleManager {
    private final String nameSpace;
    private final CuratorFramework curatorFramework;
    private final TaskItemAssignService taskItemAssignService;

    private CronExpressionContextManager cronExpressionContextManager;
    private ScheduledExecutorService cronExpressionContextManagerScheduledExecutorService;
    private ScheduledExecutorService taskItemAssignScheduledExecutorService;


    public ScheduleManager(String nameSpace, CuratorFramework curatorFramework, TaskItemAssignService taskItemAssignService) {
        this.nameSpace = nameSpace;
        this.curatorFramework = curatorFramework;
        this.taskItemAssignService = taskItemAssignService;
    }

    public void start() {
        if (cronExpressionContextManagerScheduledExecutorService != null) {
            cronExpressionContextManagerScheduledExecutorService.shutdownNow();
        }
        if (taskItemAssignScheduledExecutorService != null) {
            taskItemAssignScheduledExecutorService.shutdownNow();
        }
        cronExpressionContextManagerScheduledExecutorService = buildCronExpressionContextManagerScheduledExecutorService();
        taskItemAssignScheduledExecutorService = buildTaskItemAssignScheduledExecutorService();
    }

    public void stop() {
        if (cronExpressionContextManagerScheduledExecutorService != null) {
            cronExpressionContextManagerScheduledExecutorService.shutdownNow();
        }
        if (taskItemAssignScheduledExecutorService != null) {
            taskItemAssignScheduledExecutorService.shutdownNow();
        }
    }


    public ScheduledExecutorService buildCronExpressionContextManagerScheduledExecutorService() {

        cronExpressionContextManager = new CronExpressionContextManager(nameSpace, curatorFramework);

        ScheduledExecutorService scheduledExecutorService = newSingleThreadExecutor(nameSpace);
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                try {
                    cronExpressionContextManager.refresh();
                } catch (Exception e) {
                    e.printStackTrace();
                }

            }
        }, 15, 15, TimeUnit.SECONDS);
        return scheduledExecutorService;
    }

    public ScheduledExecutorService buildTaskItemAssignScheduledExecutorService() {
        ScheduledExecutorService scheduledExecutorService = newSingleThreadExecutor(nameSpace);
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                if (cronExpressionContextManager != null) {
                    try {
                        TaskItemAssign taskItemAssign = new TaskItemAssign(cronExpressionContextManager, taskItemAssignService);
                        taskItemAssign.taskItemAssign();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }


            }
        }, 60, 60, TimeUnit.SECONDS);
        return scheduledExecutorService;
    }

    public ScheduledExecutorService newSingleThreadExecutor(final String nameSpace) {
        return Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                return new Thread(r, nameSpace + "-" + r.getClass().getSimpleName());
            }
        });
    }
}
